<?php

namespace app\api\service;

use app\api\logic\CacheLogic;
use think\facade\Db;
use think\facade\Log;
use app\api\model\ProductMerge as ProductMergeModel;
use app\admin\model\Images as AdminImagesModel;
use app\admin\model\MinerVideos as MinerVideosModel;
use app\admin\model\Algorithm as AlgorithmModel;
use app\api\model\Inventory;
use app\api\model\Product as ProductModel;
use app\api\logic\ProductMergeLogic;

class ProductMerge
{

    protected $refresh = false;
    protected $logic;

    public function __construct()
    {
        $this->refresh = env('ENV_REFRESH_CACHE', false);
        $this->logic = new ProductMergeLogic();
    }

    /**
     * @describe 根据urlname 获取聚合商ID
     * @author: Bobo
     * @date: 2025-04-24 11:02:55 
     * @param [type] @required
     * @return Renderable
     */
    public function getProductMergeId($urlname)
    {
        if (empty($urlname)) return null;
        $id = ProductMergeModel::where('producturlname', $urlname)->where('is_del', 0)->value('id');
        return ['id' => $id];
    }

    /**
     * @describe
     * @author: Bobo
     * @date: 2025-04-24 11:18:40 
     * @param  $where 查询条件
     * @param  $role 角色
     * @param  $lang 语言
     * @param  $page 页码
     * @param  $page_size 每页条数
     * @return Renderable
     */
    public function getProductMergeList($where, $role, $lang, $page = 1, $page_size = 10)
    {
        try {

            // 获取数据
            $list = $this->logic->getProductsFromCache();

            // 翻译对应语种
            $list = (array) translate($list, $lang, ['productname', 'describe', 'inventory_type_text'], ['productname', 'describe', 'inventory_type_text']);

            // 处理文字搜索条件
            $this->logic->processNameFilters($where);

            // 应用过滤条件
            $data = $this->logic->applyFilters($list, $where, $role);

            // 应用排序
            $this->logic->applySorting($data, $where);

            // 获取价格范围
            $priceRange = $this->logic->getPriceRange($data);

            // 分页处理
            $paginatedData = $this->logic->paginateData($data, $page, $page_size);


            return array_merge($paginatedData, $priceRange);
        } catch (\Exception $e) {
            // 记录错误日志
            Log::error('获取商品列表失败 message:' . $e->getMessage() . ' file:' . $e->getFile() . ' line:' . $e->getLine() . ' where:' . json_encode($where)  . ' trace:' . $e->getTraceAsString());
            return [
                'list' => [],
                'max_price' => null,
                'min_price' => null,
                'total' => 0,
                'page' => $page,
                'page_size' => $page_size,
                'total_page' => 0
            ];
        }
    }


    /**
     * @describe
     * @author: Bobo
     * @date: 2025-04-16 11:43:14
     * @param [type] @required
     * @return Renderable
     */
    public function getProductMergeDetail($where, $ccNameId, $lang)
    {
        try {
            // 获取商品基础数据
            $cacheLogic = new CacheLogic();
            $list  = $cacheLogic->getAllProducts($this->refresh);
            $list = array_column($list, null, 'id');

            $productModel = new ProductModel();
            $computing_unit = $productModel->getAttributes('computing_unit'); // 获取算力单位

            $detail = $list[$where['id']] ?? [];
            if (empty($detail)) {
                return [];
            }

            // 聚合商品关联的所有SKU商品/配件
            $detail['ProductRelation'] =  array_column($detail['ProductRelation'], null, 'pid');

            // 过滤搭配销售商品 如果当前国家分类ID不在批次的国家分类ID中，则删除该批次
            foreach ($detail['sales_products'] as &$sales_products) {
                foreach ($sales_products['ccname_ids'] as $sales_ccname_id_key => $sales_ccname_id) {
                    $sales_ccname_id = array_unique(explode(',', implode(',', $sales_ccname_id)));
                    if (!in_array($ccNameId, $sales_ccname_id) && !in_array(0, $sales_ccname_id)) {
                        unset($sales_products['batch']->$sales_ccname_id_key);
                    }
                }
                unset($sales_products['ccname_ids']);
            }
            // 将 sales_products 转换为索引数组
            $detail['sales_products'] = array_values($detail['sales_products']);


            // 构建基础数据
            $data = $this->buildBaseData($detail, $where['sku_id'] ? $where['sku_id'] : $detail['primary_pid']);

            $data['hashrate'] = $data['hashrate'] ? $data['hashrate'] . ' ' . $computing_unit[$data['computing_unit']] : ''; // 获取算力单位
            unset($data['computing_unit']);

            $detailRelation = [];
            if (isset($where['sku_id']) && $where['sku_id'] > 0) {
                // 如果指定了sku_id，获取对应的ProductRelation
                $detailRelation = $detail['ProductRelation'][$where['sku_id']] ?? [];

                // 获取文章ID
                $article = Db::name('articles')
                    ->where('is_del', 0)
                    ->field('id,title,photo,create_time')
                    ->whereRaw('FIND_IN_SET(?, pids)', [$where['sku_id']])
                    ->order('create_time desc')
                    ->find();
                $data['article_id'] = $article['id'] ?? 0;

                // 初始化数组
                $prices = [];
                $discount_prices = [];

                $prices = array_column($detailRelation['Inventory'], 'price');

                foreach ($detailRelation['Inventory'] ?? [] as $key => $value) {
                    array_map(function ($priceDiscount) use (&$discount_prices) {
                        if ($priceDiscount['level'] == 1) {
                            $discount_prices[] = $priceDiscount['price'];
                        }
                    }, $value['priceDiscounts']); // 获取所有库存的一级折扣价格
                }
                $data['max_price'] = !empty($prices) ? max($prices) : '';
                $data['min_price'] = !empty($prices) ? min($prices) : '';
                $data['max_first_discount_price'] = !empty($discount_prices) ? max($discount_prices) : '';
                $data['min_first_discount_price'] = !empty($discount_prices) ? min($discount_prices) : '';

                // 处理批次相关逻辑
                $data['is_in_stock'] = false; // 默认无库存

                if (!empty($where['batch'])) {
                    // 检查批次是否存在于当前SKU对应的库存中
                    if (array_key_exists($where['batch'], $detailRelation['batch'])) {
                        // 根据SKUID、batch、$ccNameId 获取详细的库存记录
                        $inventory = $this->chooseInventoryDataByBatchAndCcnameId(
                            $detailRelation['product_id'],
                            $where['batch'],
                            $ccNameId
                        );

                        if ($inventory) {
                            $data['price'] = $inventory['price'] ?? '';
                            $data['Inventory'] = $inventory;
                            $data['is_in_stock'] = true;

                            // 获取一级折扣价格
                            if (!empty($inventory['priceDiscounts'])) {
                                foreach ($inventory['priceDiscounts'] as $item) {
                                    if ($item['level'] == 1) {
                                        $data['first_discount_price'] = $item['price'];
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                // 没有指定sku_id，获取主商品ProductRelation的batch
                $detailRelation = $detail['ProductRelation'] ? $detail['ProductRelation'][$detail['primary_pid']] : [];
                $data['is_in_stock'] = false;
            }

            if (empty($detailRelation)) {
                return [];
            }

            $data['related_product_merge'] = [];
            // 获取相关配件&产品
            if (!empty($detailRelation)) {
                foreach ($detailRelation['relatedProductMerge'] as $key => &$value) {
                    if (!isset($list[$value])) {
                        // 可以选择跳过，或者给默认值
                        continue;
                    }
                    $data['related_product_merge'][$key] = [
                        'id' => $list[$value]['id'],
                        'name' => $list[$value]['productname'],
                        'urlname' => $list[$value]['producturlname'],
                        'image' => $list[$value]['main_photo'][0]['url'] ?? '',
                        'max_price' => $list[$value]['max_price'] ?? '',
                        'min_price' => $list[$value]['min_price'] ?? '',
                        'max_first_discount_price' => $list[$value]['max_first_discount_price'] ?? '',
                        'min_first_discount_price' => $list[$value]['min_first_discount_price'] ?? '',
                        'hashrate' => (!empty($list[$value]['hashrate']) && isset($list[$value]['computing_unit'], $computing_unit[$list[$value]['computing_unit']])) ? $list[$value]['hashrate'] . ' ' . $computing_unit[$list[$value]['computing_unit']] : '',
                        'power' => $list[$value]['power'] ? $list[$value]['power'] . ' W' : '',
                        'inventory_type' => $list[$value]['inventory_type'] ?? '',
                        'inventory_type_text' => $list[$value]['inventory_type_text'] ?? '',
                        'describe' => $list[$value]['describe'] ?? '',
                        'type' => (int)$list[$value]['type'] ?? '',
                        'primary_brand' => $list[$value]['primary_brand'] ?? '--',
                    ];
                }
                $data['related_product_merge'] = translate(array_values($data['related_product_merge']), $lang, ['name', 'describe', 'inventory_type_text'], ['name', 'describe', 'inventory_type_text']);
            }

            $data['batch'] = $detailRelation['batch'] ?? [];
  
            // 如果当前国家分类ID不在批次的国家分类ID中，则删除该批次 并返回前端需要的正常数据
            foreach ($data['batch'] ?? [] as $key => $batch) {
                $data['batch'][$key] = $batch['batch'];
                if (!in_array($ccNameId, $batch['ccname_ids']) && !in_array(0, $batch['ccname_ids'])) {
                    unset($data['batch'][$key]);
                }
            }
            if (
                (isset($where['sku_id']) && $where['sku_id'] > 0) &&
                (isset($where['batch']) && $where['batch'])
                && !isset($data['Inventory'])
            ) {
                $data['batch'] = [];
            }


            $data['algorithm'] = $detailRelation['algorithm_value'] ?? '';


            if (isset($detailRelation['algorithm_value']) && !empty($detailRelation['algorithm_value'])) {

                $data['minable_coins'] =  Db::name('product_currency')
                    ->where('is_del', 0)
                    ->where('if_show', 1)
                    ->whereIn('algorithm', $detailRelation['algorithm'])
                    ->column('id,image,name_short as name');
            }


            // 构建规格数据
            $data['spec'] = $this->buildSpecData($detailRelation);

            return $this->translateDetail($data, $lang);
        } catch (\Exception $e) {
            // 记录详细错误日志
            Log::error('获取商品详情失败 message:' . $e->getMessage() . ' file:' . $e->getFile() . ' line:' . $e->getLine() . ' where:' . json_encode($where) . ' ccNameId:' . $ccNameId . ' trace:' . $e->getTraceAsString());

            return [
                'code' => 500,
                'message' => '获取商品详情失败',
                'data' => []
            ];
        }
    }

    /**
     * 构建基础数据
     */
    private function buildBaseData($detail, $sku_id)
    {
        return [
            'id' => $detail['id'],
            'price' => $detail['price'] ?? '',
            'first_discount_price' => $detail['first_discount_price'] ?? '',
            'min_price' => $detail['min_price'] ?? 0,
            'max_price' => $detail['max_price'] ?? 0,
            'min_first_discount_price' => $detail['min_first_discount_price'] ?? 0,
            'max_first_discount_price' => $detail['max_first_discount_price'] ?? 0,
            'name' => $detail['productname'],
            'primary_pid' => $detail['primary_pid'],
            'sku_option' => $detail['sku_option'] ?? [],
            'product_photo' => $detail['product_photo'] ?? [],
            'closeshots_photo' => $detail['closeshots_photo'] ?? [],
            'match' => $detail['sales_products'] ?? [],
            'describe' => $detail['describe'] ?? '',
            'pmv' => $detail['pmv_id'] ?? [],
            'smv' => $detail['smv_id'] ?? [],
            'full_describe' => $detail['full_describe'] ? htmlspecialchars_decode($detail['full_describe'], ENT_QUOTES) : '',
            'hashrate' => $detail['ProductRelation'][$sku_id]['hashrate'] ?? '',
            'computing_unit' => $detail['ProductRelation'][$sku_id]['computing_unit'] ?? '',
            'power' => $detail['ProductRelation'][$sku_id]['power'] ? $detail['ProductRelation'][$sku_id]['power'] . ' W' : '',
            'spec' => $detail['spec'] ?? '',
            'buy_from_other_site' => $detail['ProductMergeBuylink'] ?? [],
            'producturlname' => $detail['producturlname'],
            'seotitle' => $detail['seotitle'],
            'seodesc' => $detail['seodesc'],
            'type' => $detail['type'] ?? 1,
        ];
    }


    /**
     * 构建规格数据
     * @param array $data
     * @return array
     */
    private function buildSpecData($data)
    {
        return array_filter([
            'Product Name' => $data['name'] ?? '',
            'Also known as' => $data['abbr'] ?? '',
            'Brand' => $data['brand_value'] ?? '',
            'Model/Color' => $data['color_specs'] ?? '',
            'Condition' => $data['condition'] == 0 ? 'New' : 'Used',
            'Warranty' => $data['expiration_date'] ? $data['expiration_date'] . 'Days' : '',
            'RAM' => $data['memory_size'] ? $data['memory_size'] . 'GB' : '',
            'Chip Number' => $data['chip_number'] ?? '',
            'Working Mode' => $data['working_mode'] ?? '',
            'Power Consumption' => $data['power'] ? $data['power'] . ' W' : '',
            'Input Voltage' => $data['working_voltage'] ?? '',
            'Noise level' => $data['noise_level'] ?? '',
            'Network Connection Mode' => $data['network_conn_method'] ?? '',
            'Operation Temperature' => $data['operation_temperature'] ?? '',
            'Operation Humidity' => $data['working_humidity'] ?? '',
            'Cooling Way' => $data['colling_method'] ?? '',
            'Net Weight' => $data['weight'] ? $data['weight'] . 'kg' : '',
            'Gross Weight' => $data['gross_weight'] ? $data['gross_weight'] . 'kg' : '',
            'Net Dimensions' => $data['bare_macheine_size'] ? $data['bare_macheine_size'] . 'mm' : '',
            'Package Dimensions' => $data['package_size'] ? $data['package_size'] . 'mm' : '',
            'PSU included' => $data['has_powersource'] !== null ? ($data['has_powersource'] ? 'Yes' : 'No') : '',
            'Power Cord included' => $data['has_powerline'] !== null ? ($data['has_powerline'] ? 'Yes' : 'No') : '',
            'Power Cord Specification' => $data['powerline_specs'] ?? '',
            'Power Cord/Plug Standard' => $data['powerline_standards'] ?? '',
            'Free Shipping' => $data['free_shipping'] ? 'Yes' : 'No',
            'Magnets included' => $data['has_magnetic'] !== null ? ($data['has_magnetic'] ? 'Yes' : 'No') : '',
            'Battery included' => $data['contain_battery'] !== null ? ($data['contain_battery'] ? 'Yes' : 'No') : '',
        ], fn($value) => $value !== '' && $value !== null);
    }

    private function translateDetail($detail, $lang)
    {
        $detail['name'] = $detail['name'] ? translateOne($detail['name'], $lang) : '';
        $detail['describe'] = $detail['describe'] ? translateOne($detail['describe'], $lang) : '';
        $detail['full_describe'] = $detail['full_describe'] ? translateOne($detail['full_describe'], $lang) : '';
        if (is_array($detail['sku_option'])) {
            foreach ($detail['sku_option']   as  &$value) {
                $value['name'] = translateOne($value['name'], $lang);
            }
        }

        if (isset($detail['spec']['Product Name'])) $detail['spec']['Product Name'] = translateOne($detail['spec']['Product Name'], $lang);
        if (isset($detail['spec']['Also known as'])) $detail['spec']['Also known as'] = translateOne($detail['spec']['Also known as'], $lang);
        if (isset($detail['spec']['Brand'])) $detail['spec']['Brand'] = translateOne($detail['spec']['Brand'], $lang);

        if (is_array($detail['spec'])) {
            $newSpec = [];
            foreach ($detail['spec'] as $specKey => $specValue) {
                // 将键名转换为翻译以后的值
                $newKey = translateOne($specKey, $lang);
                $newSpec[$newKey] = $specValue;
            }
            $detail['spec'] = $newSpec;
        }


        if (is_array($detail['algorithm'])) {
            foreach ($detail['algorithm'] as &$algorithm) {
                $algorithm = translateOne($algorithm, $lang);
            }
        }
        if (isset($detail['minable_coins']) && is_array($detail['minable_coins'])) {
            foreach ($detail['minable_coins'] as &$coin) {
                $coin['name'] = translateOne($coin['name'], $lang);
            }
        }
        if (is_array($detail['match'])) {
            foreach ($detail['match'] as  &$match) {
                $match['cname'] = translateOne($match['cname'], $lang);
                if ($match['batch'] == 'Spot') {
                    $match['batch'] = translateOne($match['batch'], $lang);
                }
            }
        }
        if (is_array($detail['batch'])) {
            foreach ($detail['batch'] as  &$batch) {
                if ($batch == 'Spot') {
                    $batch = translateOne($batch, $lang);
                }
            }
        }

        return $detail;
    }


    /**
     * @describe 通过商品ID 批次 和国家分类选择出一条库存
     *  首先按照 【商品ID】 和 【批次】 和 【可售国家分类】 查询出所有满足条件的库存 按照到货时间（和库存类型（在途优先））正序 排序
     *  其次按照国家分类的可售仓库排序优先级别拿出一条库存
     * @author: Bobo
     * @date: 2025-04-21 19:27:10 
     * @param [type] @required
     * @return Renderable
     */
    public function chooseInventoryDataByBatchAndCcnameId($productId, $batch, $ccNameId)
    {

        if ($batch == 'InStock') { // In Stock 是获取缓存的时候直接放进去的，所以这里可以直接拿来判断     line 965
            $where['i.is_futures'] = 0;
        } else {
            $where['i.real_arrival_date'] = $batch;
        }
        $where['i.productid'] = $productId;
        $where['i.is_del'] = 0;
        $where['i.is_sale'] = 1;

        $inventoryModel = new Inventory();
        $inventory = $inventoryModel
            ->alias('i')
            ->join('warehouse w', 'w.id = i.wid AND w.status = 1', 'INNER')
            ->join('product_price pp', 'pp.inventory_id = i.id AND pp.transaction_currency_id = 214 AND pp.is_del = 0', 'INNER')
            ->field('i.id,i.productid,pp.wid,i.arrival_date,i.real_arrival_date,i.is_futures,i.allow_zero_stock_sale,i.create_time,i.ccname_ids,w.fl_warehouse_id,pp.id as price_id,pp.price,pp.first_leg_logistics_fee')
            ->where($where)
            ->where(function ($query) {
                $query->whereRaw('(i.available_qty - i.lock_qty) > 0')
                    ->whereOr('i.allow_zero_stock_sale', 1);
            })
            ->where(function ($query) use ($ccNameId) {
                $query->whereRaw('FIND_IN_SET(?, i.ccname_ids)', [$ccNameId])
                    ->whereOr('i.ccname_ids', 0);
            })
            ->order('i.create_time')
            ->with([
                'priceDiscounts' => function ($query) {
                    $query->field(['id', 'level', 'num', 'rate', 'price', 'price_id'])->order('level', 'asc');
                }
            ])
            ->select()
            ->toArray();


        // 获取当前可售地区的一级仓库排序优先级别
        $availableWareSort = Db::name('cc_names')->where('is_del', 0)->field('sellable_wids')->find($ccNameId);
        $availableWareSort = explode(',', $availableWareSort['sellable_wids']);




        $found = false;
        $warehouse_id = 0;
        foreach ($inventory as $item) {
            // 处理大期货一级仓库ID为空的情况
            if (null == $item['fl_warehouse_id']) {
                $item['fl_warehouse_id'] = $item['wid'];
            }


            if (in_array(0, explode(',', $item['ccname_ids']))) {
                $inventory = $item;
                $found = true;
                break;
            }

            // 遍历可用仓库排序数组
            foreach ($availableWareSort as $value) {

                // 根据批次类型选择不同的匹配方式
                $isMatch = ($batch === 'InStock')
                    ? $value == $item['fl_warehouse_id']  // 现货：完全匹配
                    : $value == $item['fl_warehouse_id'] || in_array($value, explode(',', $item['fl_warehouse_id']));  // 期货：支持多个逗号隔开的ID

                if ($isMatch) {
                    if (count(explode(',', $item['fl_warehouse_id'])) > 1) {
                        $warehouse_id = $value;
                    }
                    $inventory = $item;
                    $found = true;
                    break 2;
                }
            }
        }

        // 未找到匹配项时返回空数组
        if (!$found) {
            $inventory = [];
        }

        // 如果一级仓库ID有多个，则把当前value作为库存ID，并把value设置为第一个
        if (!empty($inventory) && isset($inventory['wid']) && count(explode(',', $inventory['wid'])) > 1) {
            if ($warehouse_id == 0) {
                $inventory['wid'] = intval(explode(',', $inventory['wid'])[0]);
                $inventory['fl_warehouse_id'] = intval(explode(',', $inventory['wid'])[0]);
            } else {
                $inventory['wid'] = intval($warehouse_id);
                $inventory['fl_warehouse_id'] = intval($warehouse_id);
            }
        }
        return $inventory;
    }

    /**
     * 获取聚合产品数据
     */
    public function getProductMergeData()
    {
        // 1. 获取基础聚合商品数据
        $productMerge = $this->getBaseProductData();

        // 2. 获取聚合商品组合售卖SKU商品库存数据
        $allsales_products = $this->getSalesProductsInventory($productMerge);

        // 获取主SKU商品主图作为聚合商品封面图
        // 把所有的pid作为all_pid ，最后获取相关配件/商品的时候需要用到
        foreach ($productMerge as $key => &$value) {
            $value['ProductRelation'] = array_column($value['ProductRelation'], null, 'pid');

            $all_pid = array_column($value['ProductRelation'], 'pid');
            $value['all_pid'] = $all_pid;
            // 检查所有必要的键是否存在
            if (
                isset($value['primary_pid']) &&
                isset($value['ProductRelation'][$value['primary_pid']])
            ) {
                if (isset($value['ProductRelation'][$value['primary_pid']]['main_photo'])) { // 主图
                    $value['main_photo'] = $value['ProductRelation'][$value['primary_pid']]['main_photo'];
                } else {
                    $more_photo = $value['ProductRelation'][$value['primary_pid']]['photo'];
                    $value['main_photo'] = explode(',', $more_photo)[0];
                }
            } else {
                $value['main_photo'] = 0;  // 设置默认值
            }
        }

        // 3. 获取图片和视频数据
        $photoImages = $this->getPhotoImages($productMerge);
        $allVideoList = $this->getVideoList($productMerge);

        // 4. 获取基础数据列表
        $lists = $this->getBaseLists();

        // 5. 获取所有商品配件的关联关系
        $accessoriesLists = $this->getAccessories($productMerge);

        // 6. 处理每个聚合产品的数据
        foreach ($productMerge as $key => &$value1) {
            if (empty($value1['ProductRelation'])) { // 如果聚合商品关联关系为空，删除当前数据
                unset($productMerge[$key]);
                continue;
            }
            $this->processProductData($value1, $photoImages, $allVideoList, $allsales_products, $lists, $accessoriesLists);
        }

        return $productMerge;
    }

    /**
     * 获取基础产品数据
     */
    private function getBaseProductData()
    {
        $model = new ProductMergeModel();

        try {
            return $model
                ->where(['is_del' => 0, 'status' => 1])
                ->field([
                    'id',
                    'productname',
                    'producturlname',
                    'primary_pid',
                    'sales_pids',
                    'estimate_price',
                    'product_photo',
                    'closeshots_photo',
                    'pmv_id',
                    'smv_id',
                    'describe',
                    'full_describe',
                    'qanda_describe',
                    'seotitle',
                    'seodesc',
                    'views_number',
                    'sort'
                ])
                ->with([
                    'ProductRelation' => function ($query) {
                        $this->buildProductRelationQuery($query);
                    },
                    'ProductMergeBuylink' => function ($query) {
                        $query->where('is_del', 0)
                            ->where('status', 1)
                            ->field(['id', 'pm_id', 'storename', 'buylink']);
                    }
                ])
                ->select()
                ->order('sort', 'asc')
                ->toArray();
        } catch (\Exception $e) {
            Log::error('ProductMergeModel: File:' . $e->getFile() . ' Line:' . $e->getLine() . ' Error:' . $e->getMessage());
            return [];
        }
    }

    /**
     * 构建产品关系查询
     */
    private function buildProductRelationQuery($query)
    {
        $query->alias('pr')
            ->field([
                'pr.id as relation_id',  // 添加别名',
                'pr.pm_id',
                'pr.pid',
                'pr.sort',
                'pb.firmware_url',
                'p.id  as product_id',
                'p.sku',
                'p.cname',
                'p.abbr',
                'p.code',
                'p.style_code',
                'p.category',
                'p.brand',
                'p.color_specs',
                'p.condition',
                'p.expiration_date',
                'p.hashrate',
                'p.computing_unit',
                'p.power',
                'p.weight',
                'p.gross_weight',
                'p.model_id',
                'p.main_photo',
                'p.photo',
                'p.describe',
                'p.min_num',
                'p.sales_price_futures',
                'p.sales_price',
                'p.type',
                'p.has_powersource',
                'p.has_powerline',
                'p.powerline_specs',
                'p.powerline_standards',
                'p.memory_size',
                'p.chip_number',
                'p.working_mode',
                'p.algorithm',
                'p.working_voltage',
                'p.noise_level',
                'p.network_conn_method',
                'p.operation_temperature',
                'p.working_humidity',
                'p.colling_method',
                'p.bare_macheine_size',
                'p.package_size',
                'p.free_shipping',
                'p.apply_rules',
                'p.contain_battery',
                'p.has_magnetic'
            ])
            ->leftJoin('product p', 'p.id = pr.pid and pr.is_del = 0')
            ->leftJoin('product_brand pb', 'pb.id = p.brand and pb.is_del = 0')
            ->where(['p.status' => 1, 'p.is_del' => 0])
            ->order('pr.sort', 'asc')
            ->with([
                'Inventory' => function ($query) {
                    $this->buildInventoryQuery($query);
                }
            ]);
    }

    /**
     * 构建库存查询
     */
    private function buildInventoryQuery($query)
    {
        $query->alias('i')
            ->field([
                'i.productid',
                'i.wid',
                'SUM(i.available_qty) AS available_qty',
                'SUM(i.lock_qty) AS lock_qty',
                'i.real_arrival_date as arrival_date',
                'i.is_futures',
                'i.allow_zero_stock_sale',
                'MIN(i.id) as id',
                'GROUP_CONCAT(DISTINCT i.ccname_ids) as ccname_ids',
                'pp.id as price_id',
                'pp.price',
                'pp.transaction_currency_id'
            ])
            ->join('product_price pp', 'pp.inventory_id = i.id AND pp.transaction_currency_id = 214 AND pp.is_del = 0', 'INNER')
            ->where(['i.is_sale' => 1, 'i.is_del' => 0])
            ->whereNotNull('i.ccname_ids')
            ->where(function ($query) {
                $query->whereRaw('(i.available_qty - i.lock_qty) > 0')
                    ->whereOr('i.allow_zero_stock_sale', 1);
            })
            ->group('i.productid,i.wid,i.real_arrival_date,i.is_futures,i.allow_zero_stock_sale,price_id,pp.price,pp.transaction_currency_id')
            ->with([
                'priceDiscounts' => function ($query) {
                    $query->field(['id', 'level', 'num', 'rate', 'price', 'price_id']);
                }
            ]);
    }

    /**
     * 获取销售产品数据
     */
    private function getSalesProductsInventory($productMerge)
    {
        $allsales_pids = array_unique(explode(',', implode(',', array_filter(array_column($productMerge, 'sales_pids')))));
        $productModel = new ProductModel();

        $allsales_products = $productModel
            ->where('id', 'in', $allsales_pids)
            ->where('status', 1)
            ->where('is_del', 0)
            ->field('id,cname')
            ->with([
                'Inventory' => function ($query) {
                    $this->buildInventoryQuery($query);
                }
            ])
            ->select()
            ->toArray();

        $allsales_products = array_filter($allsales_products, function ($product) {
            return !empty($product['Inventory']);
        });
        return array_column($allsales_products, null, 'id');
    }

    /**
     * 获取图片数据
     */
    private function getPhotoImages($productMerge)
    {

        $allPhotoIds = array_merge(
            explode(',', implode(',', array_filter(array_column($productMerge, 'product_photo')))),
            explode(',', implode(',', array_filter(array_column($productMerge, 'closeshots_photo')))),
            explode(',', implode(',', array_filter(array_column($productMerge, 'main_photo')))),
            explode(',', implode(',', array_filter(array_column($productMerge, 'photo'))))
        );
        $photoIds = implode(',', array_filter(array_unique($allPhotoIds)));
        $imageModel = new AdminImagesModel();
        $photoImages = $imageModel->getImagesByIds($photoIds);

        return array_column($photoImages, null, 'id');
    }

    /**
     * 获取视频数据
     */
    private function getVideoList($productMerge)
    {
        $allVideoIds = array_merge(
            explode(',', implode(',', array_filter(array_column($productMerge, 'pmv_id')))),
            explode(',', implode(',', array_filter(array_column($productMerge, 'smv_id'))))
        );
        $allVideoIds = implode(',', array_filter(array_unique($allVideoIds)));

        $minerVideoModel = new MinerVideosModel();
        $allVideoList = $minerVideoModel->getVideoByIds($allVideoIds);

        return array_column($allVideoList, null, 'id');
    }

    /**
     * 获取基础数据列表
     */
    private function getBaseLists()
    {
        $productModel = new ProductModel();
        $algorithmModel = new AlgorithmModel();

        $brand = Db::name('product_brand')->where('is_del', 0)->field('id,name')->select()->toArray();
        $brand = array_column($brand, null, 'id');
        return [
            'computing_unit' => $productModel->getAttributes('computing_unit'),
            'powerline_standards' => $productModel->getAttributes('powerline_standards'),
            'algorithm' => $algorithmModel->getAttributes('algorithm'),
            'coin' => Db::name('product_currency')->where('is_del', 0)->where('if_show', 1)->field('id,name,algorithm')->select()->toArray(),
            'category' => Db::name('product_category')->where('is_del', 0)->field('id,name,solution_type')->select()->toArray(),
            'brand' => $brand
        ];
    }

    /**
     * @describe 获取配件和商品的关联数据
     * @author: Bobo
     * @date: 2025-04-24 19:13:39 
     * @param [type] @required
     * @return Renderable
     */
    public function getAccessories($productMerge)
    {
        // 1. 收集所有产品ID
        $accessories = array_reduce($productMerge, function ($carry, $value) {
            if (isset($value['all_pid']) && is_array($value['all_pid'])) {
                return array_merge($carry, $value['all_pid']);
            }
            return $carry;
        }, []);

        if (empty($accessories)) {
            return [];
        }

        $accessories = array_unique($accessories);

        // 2. 一次性获取所有配件关系
        $accessoriesLists = Db::name('product_accessories')
            ->where('status', 1)
            ->where(function ($query) use ($accessories) {
                $query->where('accessories_id', 'in', $accessories)
                    ->whereOr('product_id', 'in', $accessories);
            })
            ->field('id, product_id, accessories_id')
            ->select()
            ->toArray();

        if (empty($accessoriesLists)) {
            return [];
        }

        // 3. 收集所有需要查询的PID
        $allPids = array_unique(array_merge(
            array_column($accessoriesLists, 'product_id'),
            array_column($accessoriesLists, 'accessories_id')
        ));

        // 4. 一次性获取所有产品关系
        $productRelations = Db::name('product_relation')
            ->where('is_del', 0)
            ->where('pid', 'in', $allPids)
            ->field('id, pm_id, pid')
            ->select()
            ->toArray();

        // 5. 构建PID到PM_ID的映射 
        $pidToPmIdMap = [];
        foreach ($productRelations as $relation) {
            $pidToPmIdMap[$relation['pid']][] = $relation['pm_id'];
        }
        // 6. 处理配件列表
        foreach ($accessoriesLists as &$item) {
            $item['product_pm_id'] = isset($pidToPmIdMap[$item['product_id']])
                ? array_unique($pidToPmIdMap[$item['product_id']])
                : [];

            $item['accessories_pm_id'] = isset($pidToPmIdMap[$item['accessories_id']])
                ? array_unique($pidToPmIdMap[$item['accessories_id']])
                : [];
        }
        return $accessoriesLists;
    }

    /**
     * 处理单个产品数据
     * 1. 处理图片和视频数据
     * 2. 处理搭配销售数据
     * 3. 处理产品关系数据
     * 
     * $value 产品数据
     * $photoImages 图片数据
     * $allVideoList 视频数据
     * $allsales_products 搭配销售数据
     * $lists 基础数据
     * $accessoriesLists 配件数据
     */
    private function processProductData(&$value, $photoImages, $allVideoList, $allsales_products, $lists, $accessoriesLists)
    {
        // 处理图片和视频
        $this->processMediaData($value, $photoImages, $allVideoList);

        // 处理搭配销售数据
        $this->processSalesData($value, $allsales_products);

        // 处理产品关系数据
        $this->processProductRelationData($value, $lists, $accessoriesLists);
    }

    /**
     * 处理媒体数据
     */
    private function processMediaData(&$value, $photoImages, $allVideoList)
    {
        // 处理照片数据
        $photoTypes = ['product_photo', 'closeshots_photo', 'main_photo'];

        foreach ($photoTypes as $photoType) {
            // 检查键是否存在
            if (!isset($value[$photoType])) {
                $value[$photoType] = '';  // 如果不存在，设置为空字符串
            }
            $photoIds = array_filter(explode(',', $value[$photoType]));
            $value[$photoType] = array_filter(array_map(function ($photoId) use ($photoImages) {
                return $photoImages[$photoId] ?? null;
            }, $photoIds));
        }
        // 处理视频数据
        foreach (['pmv_id', 'smv_id'] as $videoType) {

            $videoIds = (isset($value[$videoType]) && !empty($value[$videoType]))
                ? array_filter(explode(',', $value[$videoType]))
                : [];

            $value[$videoType] = array_filter(array_map(function ($videoId) use ($allVideoList) {
                return $allVideoList[$videoId] ?? null;
            }, $videoIds));
            if(count($value[$videoType]) > 0){
                $value[$videoType] = array_values($value[$videoType]);
            }
        }
    }

    /**
     * 处理搭配销售数据
     * 
     * $value 当前聚合商品综合数据
     * $allsales_products 全部的搭配销售商品库存列表
     */
    private function processSalesData(&$value, $allsales_products)
    {

        $value['sales_pids'] = array_filter(explode(',', $value['sales_pids']));
        $value['sales_products'] = array_filter(array_map(function ($pid) use ($allsales_products) {

            if (isset($allsales_products[$pid])) {

                $ccNameIds = [];
                foreach ($allsales_products[$pid]['Inventory'] as $inventory) {
                    if (0 == $inventory['is_futures']) {
                        $ccNameIds['InStock'][] = $inventory['ccname_ids'];
                    } else {
                        $ccNameIds[$inventory['arrival_date']][] = $inventory['ccname_ids'];
                    }
                }
                $batch = array_unique(array_column($allsales_products[$pid]['Inventory'], 'arrival_date'));

                $batch = array_reduce($batch, function ($result, $item) {
                    $data = $item ? [$item => $item] : ['InStock' => 'Spot']; // 替换空元素为 'InStock' 如果 $item 为空，则返回 'InStock'
                    return array_merge($result, $data); // 合并到结果数组中
                }, []);

                $batch = (object) $batch; // 最后转换为单个对象

                return [
                    'id' => $allsales_products[$pid]['id'],
                    'cname' => $allsales_products[$pid]['cname'],
                    'batch' => $batch,
                    'ccname_ids' => $ccNameIds
                ];
            }
            return null;
        }, $value['sales_pids']));


        $value['sales_products'] = array_values($value['sales_products']);
    }

    /**
     * 处理产品关系数据
     */
    private function processProductRelationData(&$value, $lists, $accessoriesLists)
    {
        if (empty($value['ProductRelation'])) {
            return;
        }

        $prices = [];
        $discount_prices = [];
        $sku_option = [];
        $brand = [];
        $algorithm = [];
        $accessory = [];
        $solution = [];

        $primary_pid = $value['primary_pid'];
        // 拿主SKU商品的类型当作当前商品的类型
        $value['type'] = '';  // 设置默认值
        // 检查 ProductRelation 是否存在且为数组
        if (!empty($value['ProductRelation']) && is_array($value['ProductRelation'])) {
            if (isset($value['ProductRelation'][$primary_pid]['type'])) {
                $value['type'] = $value['ProductRelation'][$primary_pid]['type'];
            } elseif (!empty($value['ProductRelation'])) {
                $firstRelation = reset($value['ProductRelation']);
                $value['type'] = $firstRelation['type'] ?? '';
            }
        }

        foreach ($value['ProductRelation'] as &$relation) {
            $this->processSingleRelation($relation, $lists, $brand, $algorithm, $accessory, $solution, $accessoriesLists);


            if (!empty($relation['Inventory'])) {
                $prices = array_merge($prices, array_column($relation['Inventory'], 'price')); // 获取所有库存的价格
                $this->processInventoryData($relation);

                foreach ($relation['Inventory'] as $inventory) {
                    array_map(function ($priceDiscount) use (&$discount_prices) {
                        if ($priceDiscount['level'] == 1) {
                            $discount_prices[] = $priceDiscount['price'];
                        }
                    }, $inventory['priceDiscounts']); // 获取所有库存的一级折扣价格
                }
            }
            // 添加SKU选项
            $sku_option[] = [
                'id' => $relation['product_id'],  // 使用正确的id字段
                'name' => $relation['cname'],
                'firmware_url' => $relation['firmware_url']
            ];


            // 合并ccname_ids
            foreach (isset($relation['batch']) ? $relation['batch'] : [] as $key => $batch) {



                // // 先保存计算结果到临时变量
                // $intersected = array_reduce($batch['ccname_ids'] ?? [], function ($carry, $item) {
                //     return $carry === null ? $item : array_intersect($carry, $item);
                // });
                // // 赋值回数组
                // $relation['batch'][$key]['ccname_ids'] = $intersected;

                $relation['batch'][$key]['ccname_ids'] = array_merge(...$relation['batch'][$key]['ccname_ids']);
            }
        }

        // 根据关联商品库存的批次判断当前商品的库存类型
        $batchArr = array_column($value['ProductRelation'], 'batch');

        $inventory_type_keys = [];

        foreach ($batchArr as $batch) {
            $inventory_type_keys = array_merge($inventory_type_keys, array_keys($batch));
        }
        $inventory_type_keys = array_unique($inventory_type_keys);

        if (count($inventory_type_keys) >= 1) {
            if (in_array('InStock', $inventory_type_keys)) {
                $value['inventory_type'] = 1; // 现货
                $value['inventory_type_text'] = 'Spot'; // 现货
            } else {
                $value['inventory_type'] = 2; // 期货
                $value['inventory_type_text'] = 'Futures'; // 期货
            }
        } else {
            $value['inventory_type'] = -1; // 无库存
            $value['inventory_type_text'] = 'Available on backorder'; // Out of stock 无库存
        }

        $this->setProductInfo($value, $prices, $discount_prices, $sku_option, $brand, $algorithm, $accessory, $solution, $lists);
    }

    /**
     * 处理单个关系数据
     */
    private function processSingleRelation(&$relation, $lists, &$brand, &$algorithm, &$accessory, &$solution, $accessoriesLists)
    {
        if ($relation['category']) {
            $allCategory = array_column($lists['category'], null, 'id');

            $relation['category_value'] = $allCategory[$relation['category']]['name'];
            $currentCategory = $allCategory[$relation['category']];

            if ($currentCategory['solution_type'] != 1) { // 配件
                array_push($accessory, $relation['category']);
            } else {
                array_push($solution, $relation['category']);
            }
        }

        if ($relation['brand']) {
            if (isset($lists['brand'][$relation['brand']])) {
                array_push($brand, $relation['brand']);
                $relation['brand_value'] = $lists['brand'][$relation['brand']]['name'];
            } else {
                Log::error('品牌ID不存在: ' . $relation['brand'] . ' 商品ID: ' . $relation['pid'] . " 品牌数据: " . json_encode($lists['brand']));
            }
        }

        if ($relation['algorithm']) {
            // 只处理当前 relation 的 algorithm
            $current_algorithms = array_filter(explode(',', $relation['algorithm']), function ($v) {
                return $v !== '' && $v !== null;
            });
            $relation['algorithm_value'] = array_unique(array_map(function ($value) use ($lists) {
                return isset($lists['algorithm'][$value]) ? $lists['algorithm'][$value] : null;
            }, $current_algorithms));
            $relation['algorithm_value'] = array_filter($relation['algorithm_value']); // 过滤掉null

            // 全局算法收集（如果需要统计所有出现过的算法，可以单独合并）
            $algorithm = array_merge($algorithm, $current_algorithms);

            // 币种
            $filtered_coins = array_filter($lists['coin'], fn($coin) => in_array($coin['algorithm'], $current_algorithms));
            $relation['coin_value'] = array_column($filtered_coins, 'name');
            $relation['coin'] = array_column($filtered_coins, 'id');
        }

        if ($relation['powerline_standards']) {
            $relation['powerline_standards'] = $lists['powerline_standards'][$relation['powerline_standards']];
        }

        // 处理相关商品
        $relation['relatedProductMerge'] = $this->getRelatedroductOrAcessories($relation, $accessoriesLists);
    }

    /**
     * 处理库存数据
     */
    private function processInventoryData(&$relation)
    {
        $newInventory = [];
        foreach ($relation['Inventory'] as $inventory) {
            $this->processSingleInventory($inventory, $newInventory);
        }
        // 将当前的SKU商品所有库存数据的batch 和 ccname_ids 合并到当前商品的batch 和 ccname_ids
        $relation['Inventory'] = array_values($newInventory);
        $relation['batch'] = [];
        foreach ($relation['Inventory'] as &$inventory) {
            $ccNameIds = !empty($inventory['ccname_ids']) ? explode(',', $inventory['ccname_ids']) : [];

            if (empty($inventory['arrival_date'])) {
                // 初始化 InStock 数组
                if (!isset($relation['batch']['InStock'])) {
                    $relation['batch']['InStock'] = [
                        'batch' => 'Spot',
                        'ccname_ids' => []
                    ];
                }
                $relation['batch']['InStock']['ccname_ids'][] = $ccNameIds;
            } else {
                // 初始化到货日期对应的数组
                if (!isset($relation['batch'][$inventory['arrival_date']])) {
                    $relation['batch'][$inventory['arrival_date']] = [
                        'batch' => $inventory['arrival_date'],
                        'ccname_ids' => []
                    ];
                }
                $relation['batch'][$inventory['arrival_date']]['ccname_ids'][] = $ccNameIds;
            }
        }
        // $newInventory = [];
        // foreach ($relation['Inventory'] as $inventory) {
        //     $this->processSingleInventory($inventory, $newInventory);
        // }

        // $relation['Inventory'] = array_values($newInventory);



        // $relation['batch'] = array_unique(array_column($relation['Inventory'], 'arrival_date'));

        // // 先将空值替换为 'In Stock'
        // $relation['batch'] = array_map(function ($value) {
        //     return empty($value) ? 'In Stock' : $value;
        // }, $relation['batch']);

        // // 重新排序 并将下标In Stock 替换为 InStock
        // $relation['batch'] = array_combine(
        //     array_map(function ($key) {
        //         return $key === 'In Stock' ? 'InStock' : $key;
        //     }, array_values($relation['batch'])),
        //     array_values($relation['batch'])
        // );

        // // 在这里添加处理，确保每个库存记录的 ccname_ids 都是数组
        // foreach ($relation['Inventory'] as &$inventory) {
        //     $inventory['ccname_ids'] = !empty($inventory['ccname_ids']) ? explode(',', $inventory['ccname_ids']) : [];
        // }
    }

    /**
     * 处理单个库存数据
     */
    private function processSingleInventory($inventory, &$newInventory)
    {
        $wids = strpos($inventory['wid'], ',') !== false ?
            explode(',', $inventory['wid']) :
            [$inventory['wid']];

        foreach ($wids as $wid) {
            $uniqueKey = $this->generateInventoryKey($inventory, $wid);

            if (isset($newInventory[$uniqueKey])) {
                $this->mergeInventoryData($newInventory[$uniqueKey], $inventory, $wid);
            } else {
                $newInventory[$uniqueKey] = array_merge($inventory, ['wid' => trim($wid)]);
            }
        }
    }

    /**
     * 生成库存键
     */
    private function generateInventoryKey($inventory, $wid)
    {
        return $inventory['productid'] . '_' .
            trim($wid) . '_' .
            ($inventory['arrival_date'] ?: 'null') . '_' .
            $inventory['is_futures'];
    }

    /**
     * 合并库存数据
     */
    private function mergeInventoryData(&$existing, $new, $wid)
    {
        $existing['available_qty'] += $new['available_qty'];
        $existing['lock_qty'] += $new['lock_qty'];

        $ccnames = array_unique(array_merge(
            $existing['ccname_ids'] ? explode(',', $existing['ccname_ids']) : [],
            $new['ccname_ids'] ? explode(',', $new['ccname_ids']) : []
        ));
        $existing['ccname_ids'] = implode(',', $ccnames);

        $existing = array_merge($existing, array_diff_key(
            array_merge($new, ['wid' => trim($wid)]),
            array_flip(['available_qty', 'lock_qty', 'ccname_ids'])
        ));
    }

    /**
     * 设置产品信息
     */
    private function setProductInfo(&$value, $prices, $discount_prices, $sku_option, $brand, $algorithm, $accessory, $solution, $lists)
    {
        $value['sku_option'] = $sku_option;

        $value['max_price'] = !empty($prices) ? max($prices) : '';
        $value['min_price'] = !empty($prices) ? min($prices) : '';
        $value['max_first_discount_price'] = !empty($discount_prices) ? max($discount_prices) : '';
        $value['min_first_discount_price'] = !empty($discount_prices) ? min($discount_prices) : '';



        if (!empty($value['ProductRelation'])) {
            $this->setHashrateInfo($value, $lists);
        }

        if ($value['ProductRelation'][$value['primary_pid']]['brand']) {
            $primary_brand = $value['ProductRelation'][$value['primary_pid']]['brand'];
            $value['primary_brand'] = $lists['brand'][$primary_brand]['name'];
        } else {
            $value['primary_brand'] = '--';
        }
        $value['brand'] = !empty($brand) ? array_unique($brand) : [];
        $value['algorithm'] = !empty($algorithm) ? $algorithm : [];
        $value['coin'] = [];

        if ($algorithm) {
            // 从 $lists['coin'] 中筛选出匹配算法的币种ID
            $value['coin'] = array_map(function ($item) {
                return $item['id'];
            }, array_filter($lists['coin'], function ($coin) use ($algorithm) {
                return in_array($coin['algorithm'], $algorithm);
            }));
        }
        $value['accessory'] = !empty($accessory) ? $accessory : [];
        $value['solution'] = !empty($solution) ? $solution : [];
    }

    /**
     * 设置算力信息
     */
    private function setHashrateInfo(&$value, $lists)
    {
        $current_relation = reset($value['ProductRelation']);
        $computing_unit_index = $current_relation['computing_unit'] ?? '';
        $hashrate = $current_relation['hashrate'] ?? '';
        $value['hashrate'] = $hashrate . ($computing_unit_index ? ' ' . $lists['computing_unit'][$computing_unit_index] : '');
        $value['power'] = $current_relation['power'] ? $current_relation['power'] . ' W' : '';
    }
    /**
     * @describe 获取相关产品或配件
     * @author: Bobo
     * @date: 2025-04-25 11:32:35 
     * @param $relation [arr] @required  当前商品 
     * @param $accessoriesLists [arr] @required 所有商品配件的关联关系
     * @return Renderable
     */
    public function getRelatedroductOrAcessories($relation, $accessoriesLists)
    {
        if (empty($accessoriesLists)) {
            return [];
        }
        // 根据类型确定要使用的字段
        $searchField = $relation['type'] == 1 ? 'product_id' : 'accessories_id';
        $targetField = $relation['type'] == 1 ? 'accessories_id' : 'product_id';
        $pmIdField = $relation['type'] == 1 ? 'accessories_pm_id' : 'product_pm_id';

        // 1. 首先找到所有匹配的配件关系
        $matchedItems = array_filter($accessoriesLists, function ($item) use ($relation, $searchField) {
            return $item[$searchField] == $relation['pid'];
        });

        if (empty($matchedItems)) {
            return [];
        }

        // 2. 提取目标ID列表
        $targetIds = array_unique(array_column($matchedItems, $targetField));

        // 3. 找到所有相关的产品
        $relatedItems = array_filter($accessoriesLists, function ($item) use ($targetIds, $targetField) {
            return in_array($item[$targetField], $targetIds);
        });

        if (empty($relatedItems)) {
            return [];
        }

        // 4. 提取并处理PM_ID
        $pmIds = array_column($relatedItems, $pmIdField);

        // 5. 确保所有元素都是数组并合并
        $pmIds = array_map(function ($item) {
            return is_array($item) ? $item : [$item];
        }, $pmIds);
        // 6. 合并所有数组并去重
        return array_unique(array_merge(...$pmIds));
    }
}
